import yaml, logging, sys, os
from logging.handlers import TimedRotatingFileHandler, RotatingFileHandler

# 读取启动文件绝对路径
main_dir = os.path.dirname(sys.argv[0])
# 默认yaml文件名
default_yml_name = 'application'
active_env = None

"""
    加载配置文件
"""



default_yml_path = os.path.join(main_dir, f"resource/{default_yml_name}.yml")


def load_config():
    global active_env
    if os.path.exists(default_yml_path):
        with open(default_yml_path, mode="r", encoding="utf-8") as yml_r:
            # 加载默认配置文件
            yaml_default_dict = yaml.safe_load(yml_r.read())
            active_env = yaml_default_dict.get('active-env')
        # 使用了环境才加载环境配置文件
        if active_env is not None:
            with open(os.path.join(main_dir, f"resource/{default_yml_name}-{active_env}.yml"), mode="r",
                      encoding="utf-8") as env_yml_r:
                yaml_env_dict = yaml.safe_load(env_yml_r.read())

        return {**yaml_default_dict, **yaml_env_dict}


config_dict = load_config()

"""
    配置自动注入类装饰器,prefix是配置文件前缀
"""


def configuration_properties(prefix):
    """
	:param prefix: yaml配置前缀
	:return: 装饰类
	"""

    def decorator(cls):
        """
			根据前缀自动将yml中的配置注入到类的属性中
		"""
        if config_dict is not None:
            cls_config = config_dict.get(prefix)
            if cls_config is not None:
                for name, value in cls_config.items():
                    setattr(cls, name, value)
        return cls

    return decorator


"""
	加载日志配置
"""
LEVELS = {
    'debug': logging.DEBUG,
    'info': logging.INFO,
    'warning': logging.WARNING,
    'error': logging.ERROR,
    'critical': logging.CRITICAL
}


@configuration_properties("logging")
class LogConfig:
    level = {"root": "info"}
    file = {
        "path": "resource/app.log"
    }
    pattern = {"file": "", "console": ""}
    rolling = None


log_config = LogConfig()


def set_level(ready_logger, name):
    level_name = log_config.level.get(name, 'info')
    level = LEVELS.get(level_name, logging.INFO)
    ready_logger.setLevel(level)


"""
    获取日志格式化器
"""


def get_formatter(pattern):
    if pattern:
        return logging.Formatter(pattern)


"""
    获取日志处理器
"""


def get_handler(log_config_param):
    if log_config_param.file:
        handler = logging.FileHandler(log_config_param.file.get("path"))
        handler.setFormatter(get_formatter(log_config_param.pattern.get("file")))
        return handler


rolling_handler = None

"""
	日志滚动处理器获取
"""


def get_rolling_handler(rolling_config):
    global rolling_handler
    if rolling_config:
        file_path = rolling_config.get("filePath")
        if rolling_config.get("time"):
            rolling_handler = TimedRotatingFileHandler(
                file_path,
                when=rolling_config.get("time").get("when"),
                interval=rolling_config.get("time").get("interval"),
                backupCount=rolling_config.get("time").get("backupCount")
            )
        elif rolling_config.get("size"):
            rolling_handler = RotatingFileHandler(
                file_path,
                maxBytes=rolling_config.get("size").get("maxBytes"),
                backupCount=rolling_config.get("size").get("backupCount")
            )
        rolling_handler.setFormatter(get_formatter(log_config.pattern.get("file")))
        return rolling_handler


"""
	生成配置文件日志处理器最终列表
"""
console_handler = logging.StreamHandler()
console_handler.setFormatter(get_formatter(log_config.pattern.get("console")))
handler_list = [console_handler, get_handler(log_config), get_rolling_handler(log_config.rolling)]

"""
	给定日志器名创建对应的日志记录器，基于配置
"""


def get_logger(name):
    ready_logger = logging.getLogger(name)
    set_level(ready_logger, name)
    for handler in handler_list:
        if handler is not None:
            ready_logger.addHandler(handler)
    return ready_logger


# 创建全局日志记录器
logger = get_logger("root")

# 全局IOC容器
